import {
  PutRes,
  PostRes,
  TonOrder,
  PageData,
  BookQuery,
  NotchQuery,
  WithPasterList,
  WithStockTotal,
  getTonOrderDto,
  putTonOrderDto,
  TonOrderGateway,
  postTonOrderDto,
  getOrderByTradeIdDto,
  getTonOrderBookStatDto,
  getTonOrderNotchStatDto,
  TonOrderNotchStatGateway,
  TonOrderBookStatGateway,
  getOrderAfterBookSortDto,
  getOrderAfterNotchSortDto,
  TonOrderReadInterfaceWithGrant,
  TonOrderWriteInterfaceWithGrant,
  TonOrderBookStatInterfaceWithGrant,
  TonOrderNotchStatInterfaceWithGrant,
  doBackupTonOrderDto,
  Media,
} from "qqlx-core";

import { ViewBase, ViewBaseAction } from "../view-base";
import { TonOrderSchema } from "@/river/ton-order";

export class ViewTonOrder
  extends ViewBase<TonOrder>
  implements
    ViewBaseAction<TonOrder>,
    TonOrderReadInterfaceWithGrant<{}>,
    TonOrderWriteInterfaceWithGrant<{}>,
    TonOrderBookStatInterfaceWithGrant<{}>,
    TonOrderNotchStatInterfaceWithGrant<{}>
{
  private static instance: ViewTonOrder;
  static getInstance(options?: { isSingleton?: boolean }) {
    if (options?.isSingleton === false) {
      return new ViewTonOrder();
    }

    if (!this.instance) this.instance = new ViewTonOrder();
    return this.instance;
  }

  private constructor() {
    super();
    this.initial();
    this.insertDefaultCondition();
  }

  getSchema(): TonOrder {
    return new TonOrderSchema();
  }

  // read

  async get(input: Omit<getTonOrderDto, "page" | "conditionList">) {
    this.pending();
    const base = { page: this.data.entityListPage, conditionList: this.data.conditionList };
    const dto = { ...input, ...base };

    const path = TonOrderGateway.path;
    const res = await this.$request.getByPut<getTonOrderDto, PageData<WithPasterList & TonOrder & WithStockTotal>>(path, dto);
    this.data.entityListTotal = res.total;
    return res;
  }

  getOrderByTradeId(dto: getOrderByTradeIdDto) {
    this.pending();
    const path = TonOrderGateway.path + "/tradeId";
    return this.$request.getByPut<getOrderByTradeIdDto, PageData<WithPasterList & TonOrder>>(path, dto);
  }

  async getOrderAfterBookSort(input: Omit<getOrderAfterBookSortDto, "page" | "conditionList">) {
    this.pending();
    const base = { page: this.data.entityListPage, conditionList: this.data.conditionList };
    const dto = { ...input, ...base };

    const path = `${TonOrderGateway.path}/book/sort`;
    const res = await this.$request.getByPut<getOrderAfterBookSortDto, PageData<WithPasterList & TonOrder>>(path, dto);
    this.data.entityListTotal = res.total;
    return res;
  }

  async getOrderAfterNotchSort(input: Omit<getOrderAfterNotchSortDto, "page" | "conditionList">) {
    this.pending();
    const base = { page: this.data.entityListPage, conditionList: this.data.conditionList };
    const dto = { ...input, ...base };

    const path = `${TonOrderGateway.path}/notch/sort`;
    const res = await this.$request.getByPut<getOrderAfterNotchSortDto, PageData<WithPasterList & TonOrder & WithStockTotal>>(path, dto);
    this.data.entityListTotal = res.total;
    return res;
  }

  // stat

  getTonOrderBookStat(dto: getTonOrderBookStatDto) {
    const path = TonOrderBookStatGateway.path;
    return this.$request.getByPut<getTonOrderBookStatDto, (BookQuery & { total: number })[]>(path, dto);
  }

  getTonOrderNotchStat(dto: getTonOrderNotchStatDto) {
    const path = TonOrderNotchStatGateway.path;
    return this.$request.getByPut<getTonOrderNotchStatDto, (NotchQuery & { total: number })[]>(path, dto);
  }

  // write

  async postSync(input: Omit<postTonOrderDto, "schema">) {
    this.pending();
    const dto: postTonOrderDto = { ...input, schema: this.data.schema };
    const res = await this.$request.post<postTonOrderDto, PostRes<TonOrder>>(TonOrderGateway.path, dto);
    return res;
  }

  async put() {
    this.pending();
    const dto = { schema: this.data.schema };
    return this.$request.put<putTonOrderDto, PutRes<TonOrder>>(TonOrderGateway.path, dto);
  }

  async doBackup(dto: doBackupTonOrderDto) {
    this.pending();
    const path = `${TonOrderGateway.path}/backup`;
    return this.$request.patch<doBackupTonOrderDto, { media: Media }>(path, dto);
  }
}
